﻿using System;
using System.IO;
using System.ServiceModel;
using RFServer.ServiceWCF;

namespace RFServer.Monitor
{
    class Watcher
    {
        private FileSystemWatcher watcher;

        /// <summary>
        /// Конструктор экземпляра класса
        /// </summary>

        public Watcher()
        {
            watcher = new FileSystemWatcher();
        }

        /// <summary>
        /// Наблюдение за изменениями во всех локальных файловых
        /// систем компьютера, в зависимости от настроек Setup
        /// </summary>

        public static void Autowatch()
        {
            if (Setup.Watcher)
                Watch();
        }

        /// <summary>
        /// Наблюдение за изменениями во всех локальных файловых
        /// систем компьютера
        /// </summary>

        public static void Watch()
        {
            /* Для каждого локального диска создаем свой экземпляр      */
            /* текущего класса, который следит за ним                   */

            foreach (DriveInfo drive in DriveInfo.GetDrives())
                if (drive.DriveType == DriveType.Fixed)
                    (new Watcher()).Watch(drive.Name);
        }
        
        /// <summary>
        /// Наблюдение за изменениями конкретной буквы диска
        /// </summary>
        /// <param name="DriveLetter"></param>

        private void Watch(string path)
        {
            try
            {
                /* Основные параметры слежения за файловой системой         */

                watcher.Path = path;
                watcher.IncludeSubdirectories = true;
                watcher.EnableRaisingEvents = true;
                watcher.NotifyFilter = NotifyFilters.DirectoryName | NotifyFilters.FileName;

                /* Добавляем события на произошедшие изменения              */

                watcher.Renamed += new RenamedEventHandler(OnRenamed);
                watcher.Deleted += new FileSystemEventHandler(OnDeleted);

                /* Сообщаем об успешном запуске                             */

                Setup.Log("[watcher]: Watch successfully started on " + path);
            }
            catch (Exception)
            {
                Setup.Log("[watcher]: Watch failed on " + path);
            }
        }

        /// <summary>
        /// Переименование
        /// </summary>
        /// <param name="source"></param>
        /// <param name="args"></param>

        private void OnRenamed(object source, RenamedEventArgs args)
        {
            if (Setup.LogAdvanced)
                Setup.Log("[watcher]: File " + args.OldFullPath + " renamed to " + args.FullPath);

            if (!ServiceControl.Status.IsRunning())
                return;

            try
            {
                ILocalService service = LocalService.Connect();
                service.FileRename(args.OldFullPath, args.FullPath);
                LocalService.Disconnect(service);
            }
            catch (Exception e)
            {
                Setup.Log("[watcher]: Error executing wcf method localService.FileRename", e);
            }
        }

        /// <summary>
        /// Удаление
        /// </summary>
        /// <param name="source"></param>
        /// <param name="args"></param>

        private void OnDeleted(object source, FileSystemEventArgs args)
        {
            if (Setup.LogAdvanced)
                Setup.Log("[watcher]: File " + args.FullPath + " was removed");

            if (!ServiceControl.Status.IsRunning())
                return;

            try
            {
                ILocalService service = LocalService.Connect();
                service.FileDelete(args.FullPath);
                LocalService.Disconnect(service);
            }
            catch (Exception e)
            {
                Setup.Log("[watcher]: Error executing wcf method localService.FileDelete", e);
            }
        }
    }
}
